package jp.co.nes.awssupport.business.logic;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;

import jp.co.nes.awssupport.business.utility.TargetAmountHelper;
import jp.co.nes.awssupport.common.base.CommonException;
import jp.co.nes.awssupport.common.bean.ContractInformationBean;
import jp.co.nes.awssupport.common.bean.MonthlyCompiledBillingBean;
import jp.co.nes.awssupport.common.bean.TaxAssignedBean;
import jp.co.nes.awssupport.common.bean.TaxGroupBean;
import jp.co.nes.awssupport.common.bean.TaxPlanBean;
import jp.co.nes.awssupport.common.utility.DateUtil;

/**
 * 税金プラン処理です。
 */
public class TaxPlanProcessing {

    /** 処理対象年月 */
    private YearMonth targetYearMonth;

    /** 契約情報管理 */
    private ContractInformationManage ciManage;

    /**
     * 処理対象年月を引数にもつコンストラクタです。
     *
     * @param targetYearMonth 処理対象年月
     */
    public TaxPlanProcessing(YearMonth targetYearMonth) {
        this.targetYearMonth = targetYearMonth;
        ciManage = new ContractInformationManage(targetYearMonth);
    }

    /**
     * 税金グループに含まれる税金プランを適用し、税金適用リストを返却します。<br>
     * 以下の場合、空リスト返却します。
     * <ul>
     * <li>税金グループに設定されている税金プランリストがnull or 空リストの場合</li>
     * </ul>
     * 【補足事項】
     * <ul>
     * <li>
     * 月次集計結果に含まれる請求額（税抜）は、小数第4位で四捨五入して小数第3位にした値の合計を、<br>
     * 小数第1位で四捨五入して整数にした値である必要があります。
     * </li>
     * <li>
     * 現状、税金プランとしては消費税に関する1つしか存在しませんが、将来、税金に関する内容が増えた場合にそなえて、
     * 複数のプランに対応できるようにしています。
     * </li>
     * </ul>
     *
     * @param mcbBean 月次集計結果
     * @return 税金適用リスト
     */
    public List<TaxAssignedBean> apply(MonthlyCompiledBillingBean mcbBean) {
        String linkedAccountId = mcbBean.getLinkedAccountId();
        ContractInformationBean ciBean = ciManage.get(linkedAccountId);
        if (ciBean == null) {
            throw new CommonException("contract information not exist(linkedAccountId=" + linkedAccountId + ")");
        }

        List<TaxAssignedBean> applyList = new ArrayList<>();
        TaxGroupBean groupBean = ciBean.getTaxGroupBean();

        if (groupBean == null) {
            // サポートポータル上で、契約情報に税金グループが関連していない場合
            throw new CommonException("group is null");
        }

        List<TaxPlanBean> planList = groupBean.getTaxPlanList();
        if (planList == null || planList.isEmpty()) {
            return applyList;
        }

        long billingAmount = mcbBean.getBillingAmount().longValueExact();
        String supportPlan = ciBean.getSupportPlan();
        TargetAmountHelper helper = new TargetAmountHelper(linkedAccountId, targetYearMonth, supportPlan);
        BigDecimal targetAmount = helper.getTargetAmountOfTax(billingAmount);

        for (TaxPlanBean planBean : planList) {
            TaxAssignedBean applyBean = new TaxAssignedBean();
            applyBean.setLinkedAccountId(linkedAccountId);
            applyBean.setYearMonth(DateUtil.toInt(targetYearMonth));
            applyBean.setAssignedPlanId(planBean.getPlanId());
            applyBean.setAssignedGroupId(groupBean.getGroupId());
            applyBean.setAssignedTaxName(groupBean.getTaxName());

            // 税額 = 課税対象額 * 税率 (小数点第11位で四捨五入)
            BigDecimal taxAmount = targetAmount.multiply(planBean.getTaxRate()).setScale(10, RoundingMode.HALF_UP);

            applyBean.setTargetAmount(targetAmount);
            applyBean.setTaxAmount(taxAmount);
            applyList.add(applyBean);
        }
        return applyList;
    }
}
